import argparse
from pathlib import Path
import datetime

'''写一个函数ls，能够实现linux系统中ls命令的部分功能，常见的三个参数选项要实现，分别是：
-a 列出所有文件，包括隐藏的文件
-l 列出文件的权限、属组、大小、最后一次修改时间等信息
-h和-l结合使用，文件大小以K、M的方式显示
'''

parser = argparse.ArgumentParser(description='list dir', add_help=False)
parser.add_argument('path', nargs='?', default='.', help='path')
parser.add_argument('-l', action='store_true', help='detail info')
parser.add_argument('-a', action='store_true', help='all files')
parser.add_argument('-h', action='store_true', help='human read size')

def list_dir(path, detail=False, all=False, human=False):

    def get_file_type(path:Path):
        if path.is_block_device():
            return 'b'
        elif path.is_char_device():
            return 'c'
        elif path.is_dir():
            return 'd'
        elif path.is_socket():
            return 's'
        elif path.is_symlink():
            return 'l'
        else:
            return '-'

    def get_file_mode(mode:int):
        sc = 'rwxrwxrwx'
        msr = ''
        for i in range(8, -1, -1):
            msr += sc[8-i] if (mode >> i) & 1 else '-'
        return msr

    def get_file_num(path:Path):
        count = 0
        if path.is_dir():
            for f in path.iterdir():
                if not f.is_dir():
                    count += 1
        else:
            count = 1
        return count

    def get_human_size(size:int, units=['', 'K', 'M', 'G', 'T', 'P']):
        index = 0
        while size >= 1000 and index+1 < len(units):
            size = size // 1000
            index += 1
        return '{}{}'.format(size, units[index])

    def ls(path, detail=False, all=False, human=False):
        pb = Path(path)
        dir = []
        for f in pb.iterdir():
            if not all and f.name.startswith('.'):
                continue
            if not detail:
                dir.append((f.name,))
            else:
                st = f.stat()
                tp = get_file_type(f)
                mode = get_file_mode(st.st_mode)
                filenums = get_file_num(f)
                sz = get_human_size(st.st_size) if human else st.st_size
                dt = datetime.datetime.fromtimestamp(st.st_mtime).strftime('%Y-%m-%d %H:%M:%S')
                dir.append((tp, mode , filenums, st.st_uid, st.st_gid, sz, dt, f.name))
        return dir

    file_list = ls(path, detail, all, human)
    return sorted(file_list, key=lambda x:x[-1])

if __name__ =='__main__':
    args = parser.parse_args()
    print(list_dir(args.path, args.l, args.a, args.h))